From 53a9311e2c5580c483904a10d18a9f2350c1081b Mon Sep 17 00:00:00 2001 From: Tarnyko Date: Thu, 13 Jun 2013 19:35:43 +0200 Subject: [PATCH] broadway: Add win32 support --- gdk/broadway/Makefile.am | 4 + gdk/broadway/broadway-server.c | 91 +++++++++++++++++--- gdk/broadway/gdkbroadway-server.c | 138 +++++++++++++++++++++++------- 3 files changed, 191 insertions(+), 42 deletions(-) diff --git a/gdk/broadway/Makefile.am b/gdk/broadway/Makefile.am index 1bbde7c312..5d714ef01c 100644 --- a/gdk/broadway/Makefile.am +++ b/gdk/broadway/Makefile.am @@ -80,7 +80,11 @@ broadwayd_SOURCES = \ broadway-output.h \ broadway-output.c +if OS_WIN32 +broadwayd_LDADD = $(GDK_DEP_LIBS) -lcrypt -lws2_32 +else broadwayd_LDADD = $(GDK_DEP_LIBS) -lrt -lcrypt +endif MAINTAINERCLEANFILES = $(broadway_built_sources) EXTRA_DIST += $(broadway_built_sources) diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c index bc283cb60e..37135c5ab8 100644 --- a/gdk/broadway/broadway-server.c +++ b/gdk/broadway/broadway-server.c @@ -20,9 +20,15 @@ #include #include #include +#ifdef G_OS_UNIX #include #include #include +#endif +#ifdef G_OS_WIN32 +#include +#include +#endif typedef struct BroadwayInput BroadwayInput; typedef struct BroadwayWindow BroadwayWindow; @@ -861,6 +867,73 @@ broadway_server_block_for_input (BroadwayServer *server, char op, } } +static void * +map_named_shm (char *name, gsize size) +{ +#ifdef G_OS_UNIX + + int fd; + void *ptr; + + fd = shm_open(name, O_RDONLY, 0600); + if (fd == -1) + { + perror ("Failed to shm_open"); + return NULL; + } + + ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); + + (void) close(fd); + + shm_unlink (name); + + return ptr; + +#elif defined(G_OS_WIN32) + + int fd; + void *ptr; + char *shmpath; + void *map = ((void *)-1); + + if (*name == '/') + ++name; + shmpath = g_build_filename (g_get_tmp_dir (), name, NULL); + + fd = open(shmpath, O_RDONLY, 0600); + if (fd == -1) + { + g_free (shmpath); + perror ("Failed to shm_open"); + return NULL; + } + + if (size == 0) + ptr = map; + else + { + HANDLE h, fm; + h = (HANDLE)_get_osfhandle (fd); + fm = CreateFileMapping (h, NULL, PAGE_READONLY, 0, (DWORD)size, NULL); + ptr = MapViewOfFile (fm, FILE_MAP_READ, 0, 0, (size_t)size); + CloseHandle (fm); + } + + (void) close(fd); + + remove (shmpath); + g_free (shmpath); + + return ptr; + +#else +#error "No shm mapping supported" + + return NULL; +#endif +} + static char * parse_line (char *line, char *key) { @@ -877,6 +950,7 @@ parse_line (char *line, char *key) p++; return p; } + static void send_error (HttpRequest *request, int error_code, @@ -1835,7 +1909,11 @@ static void shm_data_unmap (void *_data) { ShmSurfaceData *data = _data; +#ifdef G_OS_UNIX munmap (data->data, data->data_size); +#elif defined(G_OS_WIN32) + UnmapViewOfFile (data->data); +#endif g_free (data); } @@ -1851,7 +1929,6 @@ broadway_server_open_surface (BroadwayServer *server, cairo_surface_t *surface; gsize size; void *ptr; - int fd; window = g_hash_table_lookup (server->id_ht, GINT_TO_POINTER (id)); @@ -1864,17 +1941,7 @@ broadway_server_open_surface (BroadwayServer *server, size = width * height * sizeof (guint32); - fd = shm_open(name, O_RDONLY, 0600); - if (fd == -1) - { - perror ("Failed to shm_open"); - return NULL; - } - - ptr = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); - (void) close(fd); - - shm_unlink (name); + ptr = map_named_shm (name, size); if (ptr == NULL) return NULL; diff --git a/gdk/broadway/gdkbroadway-server.c b/gdk/broadway/gdkbroadway-server.c index 04565e08ae..7c1dc3490c 100644 --- a/gdk/broadway/gdkbroadway-server.c +++ b/gdk/broadway/gdkbroadway-server.c @@ -20,6 +20,9 @@ #include #include #include +#ifdef G_OS_WIN32 +#include +#endif #include "gdkintl.h" typedef struct BroadwayInput BroadwayInput; @@ -538,6 +541,85 @@ _gdk_broadway_server_window_translate (GdkBroadwayServer *server, return TRUE; } +static void * +map_named_shm (char *name, gsize size) +{ +#ifdef G_OS_UNIX + + int fd; + void *ptr; + int res; + + fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd == -1) + { + if (errno != EEXIST) + g_error ("Unable to allocate shared mem for window"); + return NULL; + } + + res = ftruncate (fd, size); + g_assert (res != -1); + + res = posix_fallocate (fd, 0, size); + if (res != 0) + { + shm_unlink (name); + g_error ("Not enough shared memory for window surface"); + } + + ptr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + + (void) close(fd); + + return ptr; + +#elif defined(G_OS_WIN32) + + int fd; + void *ptr; + char *shmpath; + void *map = ((void *)-1); + int res; + + if (*name == '/') + ++name; + shmpath = g_build_filename (g_get_tmp_dir (), name, NULL); + + fd = open(shmpath, O_RDWR|O_CREAT|O_EXCL, 0600); + g_free (shmpath); + if (fd == -1) + { + if (errno != EEXIST) + g_error ("Unable to allocate shared mem for window"); + return NULL; + } + + res = ftruncate (fd, size); + g_assert (res != -1); + + if (size == 0) + ptr = map; + else + { + HANDLE h, fm; + h = (HANDLE)_get_osfhandle (fd); + fm = CreateFileMapping (h, NULL, PAGE_READWRITE, 0, (DWORD)size, NULL); + ptr = MapViewOfFile (fm, FILE_MAP_WRITE, 0, 0, (size_t)size); + CloseHandle (fm); + } + + (void) close(fd); + + return ptr; + +#else +#error "No shm mapping supported" + + return NULL; +#endif +} + static char make_valid_fs_char (char c) { @@ -547,11 +629,12 @@ make_valid_fs_char (char c) } /* name must have at least space for 34 bytes */ -static int -create_random_shm (char *name) +static gpointer +create_random_shm (char *name, gsize size) { guint32 r; - int i, o, fd; + int i, o; + gpointer ptr; while (TRUE) { @@ -570,18 +653,11 @@ create_random_shm (char *name) name[o++] = make_valid_fs_char ((r >> 24) & 0xff); } name[o++] = 0; - - fd = shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600); - if (fd >= 0) - return fd; - if (errno != EEXIST) - { - g_printerr ("Unable to allocate shared mem for window"); - exit (1); - } + ptr = map_named_shm (name, size); + if (ptr) + return ptr; } - } static const cairo_user_data_key_t gdk_broadway_shm_cairo_key; @@ -597,8 +673,26 @@ shm_data_destroy (void *_data) { BroadwayShmSurfaceData *data = _data; +#ifdef G_OS_UNIX + munmap (data->data, data->data_size); shm_unlink (data->name); + +#elif defined(G_OS_WIN32) + + char *name = data->name; + char *shmpath; + + if (*name == '/') + ++name; + + shmpath = g_build_filename (g_get_tmp_dir (), name, NULL); + UnmapViewOfFile (data->data); + remove (shmpath); + g_free (shmpath); + +#endif + g_free (data); } @@ -608,26 +702,10 @@ _gdk_broadway_server_create_surface (int width, { BroadwayShmSurfaceData *data; cairo_surface_t *surface; - int res; - int fd; data = g_new (BroadwayShmSurfaceData, 1); data->data_size = width * height * sizeof (guint32); - - fd = create_random_shm (data->name); - - res = ftruncate (fd, data->data_size); - g_assert (res != -1); - - res = posix_fallocate (fd, 0, data->data_size); - if (res != 0) - { - shm_unlink (data->name); - g_error ("Not enough shared memory for window surface"); - } - - data->data = mmap(0, data->data_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - (void) close(fd); + data->data = create_random_shm (data->name, data->data_size); surface = cairo_image_surface_create_for_data ((guchar *)data->data, CAIRO_FORMAT_RGB24, width, height, width * sizeof (guint32)); -- 2.30.2